1 /*
2  * Copyright (c) 2011-2012 - Mauro Carvalho Chehab
3  * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation version 2.1 of the License.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18  *
19  */
20 
21 module libdvbv5_d.nit;
22 
23 import core.sys.posix.unistd;
24 
25 import libdvbv5_d.descriptors: descriptors, dvb_desc;
26 import libdvbv5_d.dvb_fe: dvb_v5_fe_parms;
27 import libdvbv5_d.header: dvb_table_header;
28 
29 extern (C):
30 
31 /* ssize_t */
32 
33 /**
34  * @file nit.h
35  * @ingroup dvb_table
36  * @brief Provides the descriptors for NIT MPEG-TS table
37  * @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
38  * @author Mauro Carvalho Chehab
39  * @author Andre Roth
40  *
41  * @par Bug Report
42  * Please submit bug report and patches to linux-media@vger.kernel.org
43  *
44  * @par Relevant specs
45  * The table described herein is defined at:
46  * - ISO/IEC 13818-1
47  * - ETSI EN 300 468
48  *
49  * @par Bug Report
50  * Please submit bug reports and patches to linux-media@vger.kernel.org
51  */
52 
53 /**
54  * @def DVB_TABLE_NIT
55  *	@brief NIT table ID
56  *	@ingroup dvb_table
57  * @def DVB_TABLE_NIT2
58  *	@brief NIT table ID (alternative table ID)
59  *	@ingroup dvb_table
60  * @def DVB_TABLE_NIT_PID
61  *	@brief NIT Program ID
62  *	@ingroup dvb_table
63  */
64 enum DVB_TABLE_NIT = 0x40;
65 enum DVB_TABLE_NIT2 = 0x41;
66 enum DVB_TABLE_NIT_PID = 0x10;
67 
68 /**
69  * @union dvb_table_nit_transport_header
70  * @brief MPEG-TS NIT transport header
71  * @ingroup dvb_table
72  *
73  * @param transport_length	transport length
74  *
75  * This structure is used to store the original NIT transport header,
76  * converting the integer fields to the CPU endianness.
77  *
78  * The undocumented parameters are used only internally by the API and/or
79  * are fields that are reserved. They shouldn't be used, as they may change
80  * on future API releases.
81  */
82 union dvb_table_nit_transport_header
83 {
84     align (1):
85 
86     ushort bitfield;
87 
88     struct
89     {
90         import std.bitmanip : bitfields;
91         align (1):
92 
93         mixin(bitfields!(
94             ushort, "transport_length", 12,
95             ushort, "reserved", 4));
96     }
97 }
98 
99 /**
100  * @struct dvb_table_nit_transport
101  * @brief MPEG-TS NIT transport table
102  * @ingroup dvb_table
103  *
104  * @param transport_id	transport id
105  * @param network_id	network id
106  * @param desc_length	desc length
107  * @param descriptor	pointer to struct dvb_desc
108  * @param next		pointer to struct dvb_table_nit_transport
109  *
110  * This structure is used to store the original NIT transport table,
111  * converting the integer fields to the CPU endianness.
112  *
113  * The undocumented parameters are used only internally by the API and/or
114  * are fields that are reserved. They shouldn't be used, as they may change
115  * on future API releases.
116  *
117  * Everything after dvb_table_nit_transport::descriptor (including it) won't
118  * be bit-mapped to the data parsed from the MPEG TS. So, metadata are added
119  * there.
120  */
121 struct dvb_table_nit_transport
122 {
123     align (1):
124 
125     ushort transport_id;
126     ushort network_id;
127 
128     union
129     {
130         align (1):
131 
132         ushort bitfield;
133 
134         struct
135         {
136             import std.bitmanip : bitfields;
137             align (1):
138 
139             mixin(bitfields!(
140                 ushort, "desc_length", 12,
141                 ushort, "reserved", 4));
142         }
143     }
144 
145     dvb_desc* descriptor;
146     dvb_table_nit_transport* next;
147 }
148 
149 /**
150  * @struct dvb_table_nit
151  * @brief MPEG-TS NIT table
152  * @ingroup dvb_table
153  *
154  * @param header	struct dvb_table_header content
155  * @param desc_length	descriptor length
156  * @param descriptor	pointer to struct dvb_desc
157  * @param transport	pointer to struct dvb_table_nit_transport
158  *
159  * This structure is used to store the original NIT table,
160  * converting the integer fields to the CPU endianness.
161  *
162  * The undocumented parameters are used only internally by the API and/or
163  * are fields that are reserved. They shouldn't be used, as they may change
164  * on future API releases.
165  *
166  * Everything after dvb_table_nit::descriptor (including it) won't be bit-mapped
167  * to the data parsed from the MPEG TS. So, metadata are added there.
168  */
169 struct dvb_table_nit
170 {
171     align (1):
172 
173     dvb_table_header header;
174 
175     union
176     {
177         align (1):
178 
179         ushort bitfield;
180 
181         struct
182         {
183             import std.bitmanip : bitfields;
184             align (1):
185 
186             mixin(bitfields!(
187                 ushort, "desc_length", 12,
188                 ushort, "reserved", 4));
189         }
190     }
191 
192     dvb_desc* descriptor;
193     dvb_table_nit_transport* transport;
194 }
195 
196 /**
197  * @brief typedef for a callback used when a NIT table entry is found
198  * @ingroup dvb_table
199  *
200  * @param nit	a struct dvb_table_nit pointer
201  * @param desc	a struct dvb_desc pointer
202  * @param priv	an opaque optional pointer
203  */
204 alias nit_handler_callback_t = void function (
205     dvb_table_nit* nit,
206     dvb_desc* desc,
207     void* priv);
208 
209 /**
210  * @brief typedef for a callback used when a NIT transport table entry is found
211  * @ingroup dvb_table
212  *
213  * @param nit	a struct dvb_table_nit pointer
214  * @param tran	a struct dvb_table_nit_transport pointer
215  * @param desc	a struct dvb_desc pointer
216  * @param priv	an opaque optional pointer
217  */
218 alias nit_tran_handler_callback_t = void function (
219     dvb_table_nit* nit,
220     dvb_table_nit_transport* tran,
221     dvb_desc* desc,
222     void* priv);
223 
224 /**
225  * @brief Macro used to find a transport inside a NIT table
226  * @ingroup dvb_table
227  *
228  * @param _tran		transport to seek
229  * @param _nit		pointer to struct dvb_table_nit_transport
230  */
231 
232 // struct dvb_v5_fe_parms;
233 
234 /**
235  * @brief Initializes and parses NIT table
236  * @ingroup dvb_table
237  *
238  * @param parms	struct dvb_v5_fe_parms pointer to the opened device
239  * @param buf buffer containing the NIT raw data
240  * @param buflen length of the buffer
241  * @param table pointer to struct dvb_table_nit to be allocated and filled
242  *
243  * This function allocates a NIT table and fills the fields inside
244  * the struct. It also makes sure that all fields will follow the CPU
245  * endianness. Due to that, the content of the buffer may change.
246  *
247  * @return On success, it returns the size of the allocated struct.
248  *	   A negative value indicates an error.
249  */
250 ssize_t dvb_table_nit_init (
251     dvb_v5_fe_parms* parms,
252     const(ubyte)* buf,
253     ssize_t buflen,
254     dvb_table_nit** table);
255 
256 /**
257  * @brief Frees all data allocated by the NIT table parser
258  * @ingroup dvb_table
259  *
260  * @param table pointer to struct dvb_table_nit to be freed
261  */
262 void dvb_table_nit_free (dvb_table_nit* table);
263 
264 /**
265  * @brief Prints the content of the NIT table
266  * @ingroup dvb_table
267  *
268  * @param parms	struct dvb_v5_fe_parms pointer to the opened device
269  * @param table	pointer to struct dvb_table_nit
270  */
271 void dvb_table_nit_print (dvb_v5_fe_parms* parms, dvb_table_nit* table);
272 
273 /**
274  * @brief For each entry at NIT and NIT transport tables, call a callback
275  * @ingroup dvb_table
276  *
277  * @param parms		struct dvb_v5_fe_parms pointer to the opened device
278  * @param table		pointer to struct dvb_table_nit
279  * @param descriptor	indicates the NIT table descriptor to seek
280  * @param call_nit	a nit_handler_callback_t function to be called when a
281  *			new entry at the NIT table is found (or NULL).
282  * @param call_tran	a nit_tran_handler_callback_t function to be called
283  *			when a new entry at the NIT transport table is found
284  *			(or NULL).
285  * @param priv		an opaque pointer to be optionally used by the
286  *			callbacks. The function won't touch on it, just use
287  *			as an argument for the callback functions.
288  *
289  * When parsing a NIT entry, we need to call some code to properly handle
290  * when a given descriptor in the table is found. This is used, for example,
291  * to create newer transponders to seek during scan.
292  *
293  * For example, to seek for the CATV delivery system descriptor and call a
294  * function that would add a new transponder to a scan procedure:
295  * @code
296  * 	dvb_table_nit_descriptor_handler(
297  *				&parms->p, dvb_scan_handler->nit,
298  *				cable_delivery_system_descriptor,
299  *				NULL, add_update_nit_dvbc, &tr);
300  * @endcode
301  */
302 void dvb_table_nit_descriptor_handler (
303     dvb_v5_fe_parms* parms,
304     dvb_table_nit* table,
305     descriptors descriptor,
306     void function () call_nit,
307     void function () call_tran,
308     void* priv);